<template>
  <section
    id="routeTabs"
    class="multiple-nav-wrap"
  >
    <div class="fixed-tags-wrapper">
      <template
        v-for="element of fixedViewsRoute"
        :key="element.fullPath"
      >
        <router-link
          :to="{ ...element }"
          :class="[
            'fixed-tags-item',
            isActiveRoute(element) ? 'active' : ''
          ]"
        >
          <div class="title-wrap">
            <span>{{ element.meta.title }}</span>
          </div>
        </router-link>
      </template>
    </div>
    <scroll-pane
      ref="scrollPaneRef"
      class="tags-wrapper"
    >
      <draggable
        :list="multipleNavList"
        item-key="fullPath"
        :animation="500"
        filter=".fixed-item"
        :scroll="true"
        class="tags-list-wrap"
        @end="dataDragEnd"
      >
        <template #item="{ element }">
          <router-link
            :to="{ ...element }"
            :class="[
              'tags-item',
              isActiveRoute(element) ? 'active' : ''
            ]"
            :full-path="element.fullPath"
            @mouseenter="currentPath = element.fullPath"
            @mouseleave="currentPath = '-'"
            @dblclick="handleCommand(3)"
          >
            <div class="title-wrap">
              <span>{{ element.meta.title }}</span>

              <span
                v-if="!element.meta.fixed"
                :class="[
                  'btn-close close',
                  setCloseBtnBg && currentPath === element.fullPath ? 'bg' : ''
                ]"
                @mouseenter="setCloseBtnBg = true"
                @mouseleave="setCloseBtnBg = false"
                @click.prevent.stop="closeNavHandle(element)"
              >
                <el-icon><close /></el-icon>
              </span>
            </div>
          </router-link>
        </template>
      </draggable>
    </scroll-pane>
    <section class="multiple-nav-options-wrap">
      <section class="refresh-route-button">
        <span
          class="btn-icon"
          @click="handleCommand(3)"
        >
          <el-icon>
            <refresh />
          </el-icon>
        </span>
      </section>
      <section class="setting-route-button">
        <el-dropdown @command="handleCommand">
          <span class="btn-icon">
            <el-icon>
              <setting />
            </el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item
                :command="3"
              >
                <span class="dropdown-item__icon-wrap">
                  <el-icon>
                    <refresh />
                  </el-icon>
                </span>
                重新加载
              </el-dropdown-item>
              <el-dropdown-item :command="4">
                <span class="dropdown-item__icon-wrap">
                  <el-icon>
                    <close />
                  </el-icon>
                </span>
                关闭标签页
              </el-dropdown-item>

              <el-dropdown-item
                :command="5"
                divided
              >
                <span class="dropdown-item__icon-wrap">
                  <el-icon>
                    <arrow-left />
                  </el-icon>
                </span>
                关闭左侧标签页
              </el-dropdown-item>
              <el-dropdown-item :command="6">
                <span class="dropdown-item__icon-wrap">
                  <el-icon>
                    <arrow-right />
                  </el-icon>
                </span>
                关闭右侧标签页
              </el-dropdown-item>

              <el-dropdown-item
                :command="1"
                divided
              >
                <span class="dropdown-item__icon-wrap">
                  <el-icon>
                    <remove />
                  </el-icon>
                </span>
                关闭其他标签页
              </el-dropdown-item>
              <el-dropdown-item :command="2">
                <span class="dropdown-item__icon-wrap">
                  <el-icon>
                    <circle-close-filled />
                  </el-icon>
                </span>
                关闭全部标签页
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </section>
    </section>
  </section>
</template>
<script lang="ts" setup name="MultipleNav">
import { watch, ref, nextTick, computed } from 'vue';

import {
  Close, Setting, Refresh, Remove, CircleCloseFilled, ArrowLeft, ArrowRight,
} from '@element-plus/icons-vue';
import { useRoute, useRouter } from 'vue-router';
import Draggable from 'vuedraggable';

import ScrollPane from './scroll-pane.vue';

import type { RouteLocationNormalizedLoaded } from 'vue-router';

import config from '@/config';
import { refreshPage, closePage } from '@/hooks';
import { useKeepAliveStore } from '@/store/keep-alive';

const router = useRouter();
const route = useRoute();
const keepAliveStore = useKeepAliveStore();

const scrollPaneRef = ref();

const multipleNavList = ref<TypeObject[]>([]);
const currentPath = ref('-');
const setCloseBtnBg = ref(false);
const fixedViewsRoute = ref<TypeObject[]>(config.multipleNav.fixedRoutes || []);

const visitedViews = computed(() => keepAliveStore.visitedViews);

const addTagHandle = (to:RouteLocationNormalizedLoaded) => {
  if(!to.meta?.title) {
    return;
  }
  keepAliveStore.addTagOnly(to);
};

const setMultipleNavList = (views:TypeObject) => {
  const navList = views[config.multipleNav.clientId] || [];
  const navListClone = JSON.parse(JSON.stringify(navList));
  multipleNavList.value = navListClone.filter((item:TypeObject) => (router.hasRoute(item.name)));
};

const moveToCurrentTag = () => {
  const navList:any = document.querySelectorAll('.tags-item');
  const scrollPaneContainer:TypeObject = scrollPaneRef.value;
  for (const nav of navList) {
    const linkFullPath = nav.getAttribute('full-path');
    if (route.fullPath === linkFullPath) {
      scrollPaneContainer.moveToCurrentTag(nav, navList, scrollPaneContainer.$el.offsetWidth);
      return;
    }
  }
};

const isActiveRoute = (routeInfo:TypeObject) => routeInfo.fullPath === route.fullPath;

const closeNavHandle = (routeInfo:TypeObject) => {
  const curIndex = multipleNavList.value.findIndex((nav) => nav.fullPath === routeInfo.fullPath);
  const preRouteInfo = multipleNavList.value[curIndex - 1] || {};
  const nextRouteInfo = multipleNavList.value[curIndex + 1] || {};
  if (isActiveRoute(routeInfo)) {
    if (preRouteInfo.fullPath) {
      router.push({
        ...preRouteInfo,
      });
    } else if (nextRouteInfo.fullPath) {
      router.push({
        ...nextRouteInfo,
      });
    } else if (fixedViewsRoute.value.length) {
      router.replace(fixedViewsRoute.value[0].fullPath || '');
    } else {
      router.replace('/');
    }
  }
  currentPath.value = '-';
  closePage(routeInfo);
};

const handleCommand = (command:number) => {
  currentPath.value = '-';
  if (command === 1) {
    keepAliveStore.deleteOtherTagAndCache(route);
  } else if (command === 2) {
    keepAliveStore.deleteAllTagAndCache();
    if (fixedViewsRoute.value.length) {
      router.replace(fixedViewsRoute.value[0].fullPath || '');
    } else {
      router.replace('/');
    }
  } else if (command === 3) {
    refreshPage(route);
  } else if (command === 4) {
    closeNavHandle(route);
  } else if (command === 5) {
    keepAliveStore.deleteLeftTagAndCache(route);
  } else if (command === 6) {
    keepAliveStore.deleteRightTagAndCache(route);
  }
};
const dataDragEnd = () => {
  if (multipleNavList.value.length > 0) {
    keepAliveStore.setVisitedViews(multipleNavList.value);
  }
};

watch(
  route,
  (routeInfo) => {
    addTagHandle(routeInfo);
    nextTick(() => {
      moveToCurrentTag();
    });
  },
  {
    immediate: true,
  }
);

watch(
  () => visitedViews.value,
  (views) => {
    setMultipleNavList(views);
  },
  {
    deep: true,
    immediate: true,
  }
);
</script>
<style lang="scss" scoped>
:deep(.#{$namespace}-dropdown) {
  line-height: normal;
}

.multiple-nav-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;

  .fixed-tags-wrapper {
    display: flex;
  }

  .tags-wrapper {
    box-sizing: border-box;
    flex: 1;

    .tags-list-wrap {
      display: flex;
      flex-wrap: nowrap;
      align-items: center;
      justify-content: flex-start;
      width: 100%;
    }
  }

  .fixed-tags-item,
  .tags-item {
    position: relative;
    display: flex;
    line-height: 28px;
    color: var(--#{$namespace}-text-color-regular);
    cursor: pointer;
    background-color: var(--maia-color-grey-4);
    border: 1px solid var(--maia-color-grey-2);
    border-right-color: var(--maia-color-grey-4);
    border-left-color: var(--maia-color-grey-4);

    .title-wrap {
      position: relative;
      display: flex;
      align-items: center;
      padding: 0 var(--maia-base-space);
      font-size: 12px;
      white-space: nowrap;
    }

    &.active {
      color: var(--#{$namespace}-color-primary);
      background-color: var(--#{$namespace}-color-white);
      border-right-color: var(--maia-color-grey-2);
      border-left-color: var(--maia-color-grey-2);

      .title-wrap {
        &::before {
          width: 8px;
        }
      }
    }

    .btn-close {
      display: flex;
      align-items: center;
      justify-content: center;

      &.close {
        width: 16px;
        height: 16px;
        margin-left: 2px;
        border-radius: 50%;

        &.bg {
          background-color: var(--maia-color-grey-base);
        }
      }
    }

    &::before {
      position: absolute;
      top: 50%;
      left: 0;
      width: 1px;
      height: 22px;
      margin-top: -11px;
      content: '';
      background-color: var(--maia-color-grey-3);
    }

    &:hover {
      background-color: var(--#{$namespace}-color-white);
    }

    &:first-child::before,
    &.active::before,
    &:hover::before {
      width: 0;
    }

    &.active + a::before,
    &:hover + a::before {
      width: 0;
    }

    &:first-child {
      border-left-color: var(--maia-color-grey-2);
      border-top-left-radius: 2px;
      border-bottom-left-radius: 2px;
    }

    &:last-child {
      border-right-color: var(--maia-color-grey-2);
      border-top-right-radius: 2px;
      border-bottom-right-radius: 2px;
    }
  }

  .multiple-nav-options-wrap {
    position: relative;
    display: flex;
    justify-content: flex-end;
    width: 62px;

    .refresh-route-button,
    .setting-route-button {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 28px;
      height: 28px;
      cursor: pointer;

      .btn-icon {
        display: flex;
        align-items: center;
        font-size: 18px;
      }
    }

    .refresh-route-button {
      &::before {
        position: absolute;
        top: 4px;
        left: 3px;
        width: 1px;
        height: 20px;
        content: '';
        border-left: 1px solid var(--#{$namespace}-border-color);
      }
    }

    .dropdown-item__icon-wrap {
      display: flex;
      font-size: 14px;
    }
  }
}
</style>
